<?php
/**
 * @file
 */

/**
 * Implements of hook_entity_info()
 */
function ffsrequirement_entity_info() {
  $return = array(
    'ffsrequirement' => array(
      'label' => t('FFS Requirements'),
      'controller class' => 'FFSRController',
      'base table' => 'ffsrequirement',
      'uri callback' => 'ffsrequirement_uri',
      'fieldable' => TRUE,
      'entity keys' => array(
        'id' => 'rid',
      ),
      'bundles' => array(
        'ffsrequirement' => array(
          'label' => t('FFS Requirements'),
          'admin' => array(
            'path' => 'admin/ffsrequirement',
            'access arguments' => array('administer content'),
          ),
        ),
      ),
      'view modes' => array(
        'full' => array(
          'label' => t('FFS Requirements'),
          'custom settings' => FALSE,
        ),
      ),
    ),
  );
  return $return;
}

/**
 * Implements callback_entity_info_uri().
 */
function ffsrequirement_uri($ffsrequirement) {
  return array(
    'path' => 'ffsrequirement/' . $ffsrequirement->rid,
    'options' => array('fragment' => 'ffsrequirement-' . $ffsrequirement->rid),
  );
}

/**
 * Implements hook_field_info_alter().
 */
function ffsrequirement_client_field_info_alter(&$info) {
  // Add the 'ffsrequirement_form' instance setting to all field types.
  foreach ($info as $field_type => &$field_type_info) {
    $field_type_info += array('instance_settings' => array());
    $field_type_info['instance_settings'] += array(
      'ffsrequirement_edit' => FALSE,
    );
  }
}

/**
 * Implements hook_field_extra_fields().
 */
function ffsrequirement_field_extra_fields() {
  $return['ffsrequirement']['ffsrequirement'] = array(
    'form' => array(
      'fullname' => array(
        'label' => t('Fullname'),
        'description' => t('fullname form elements.'),
        'weight' => -10,
      ),
      /*'department' => array(
        'label' => t('Department'),
        'description' => t('Department form elements.'),
        'weight' => -10,
      ),
      'position' => array(
        'label' => t('Position'),
        'description' => t('Position form elements.'),
        'weight' => -10,
      ),*/
      'year' => array(
        'label' => t('Working year'),
        'description' => t('Working year form elements.'),
        'weight' => -10,
      )
    ),
    'display' => array(
      'summary' => array(
        'label' => t('FFS Requirement'),
        'description' => t('ffsrequirement module client view element.'),
        'weight' => 5,
      ),
    ),
  );

  return $return;
}

/**
 * Load the entire word by wid.
 *
 * @param $wid
 *   The identifying comment id.
 * @param $reset
 *   Whether to reset the internal static entity cache. Note that the static
 *   cache is disabled in comment_entity_info() by default.
 *
 * @return
 *   The comment object.
 */
function ffsrequirement_load($rid, $reset = FALSE) {
  $ffsrequirement = ffsrequirement_load_multiple(array($rid), array(), $reset);
  return $ffsrequirement ? $ffsrequirement[$rid] : FALSE;
}

/**
 * Load word from the database.
 *
 * @param $rids
 *   An array of word IDs.
 * @param $conditions
 *   (deprecated) An associative array of conditions on the {wordgames}
 *   table, where the keys are the database fields and the values are the
 *   values those fields must have. Instead, it is preferable to use
 *   EntityFieldQuery to retrieve a list of entity IDs loadable by
 *   this function.
 * @param $reset
 *   Whether to reset the internal static entity cache. Note that the static
 *   cache is disabled in wordgame_entity_info() by default.
 *
 * @return
 *   An array of comment objects, indexed by word ID.
 *
 * @see entity_load()
 * @see EntityFieldQuery
 *
 * @todo Remove $conditions in Drupal 8.
 */
function ffsrequirement_load_multiple($rids = array(), $conditions = array(), $reset = FALSE) {
  return entity_load('ffsrequirement', $rids, $conditions, $reset);
}

/**
 * Save word
 */
function ffsrequirement_save($ffsrequirement) {
  $transaction = db_transaction();

  try {
    field_attach_presave('ffsrequirement', $ffsrequirement);

    // Determine if we will be inserting a new node.
    if (!isset($ffsrequirement->is_new)) {
      $ffsrequirement->is_new = empty($ffsrequirement->rid);
    }

    $ffsrequirement->created = REQUEST_TIME;

    // Let modules modify the node before it is saved to the database.
    module_invoke_all('ffsrequirement_presave', $ffsrequirement);
    module_invoke_all('entity_presave', $ffsrequirement, 'ffsrequirement');

    // Save the node and node revision.
    if ($ffsrequirement->is_new) {
      // For new ffsrequirement, save new records for the ffsrequirement itself
      drupal_write_record('ffsrequirement', $ffsrequirement);
      $op = 'insert';
    }
    else {
      // For existing ffsrequirement, update the ffsrequirement record which matches the value of
      // $ffsrequirement->wid.
      drupal_write_record('ffsrequirement', $ffsrequirement, 'rid');
      $op = 'update';
    }

    // Save fields.
    $function = "field_attach_$op";
    $function('ffsrequirement', $ffsrequirement);

    module_invoke_all('ffsrequirement_' . $op, $ffsrequirement);
    module_invoke_all('entity_' . $op, $ffsrequirement, 'ffsrequirement');

    // Clear internal properties.
    unset($ffsrequirement->is_new);
    // Clear the static loading cache.
    entity_get_controller('ffsrequirement')->resetCache(array($ffsrequirement->rid));

    // Ignore slave server temporarily to give time for the
    // saved ffsrequirement to be propagated to the slave.
    db_ignore_slave();
  }
  catch (Exception $e) {
    $transaction->rollback();
    watchdog_exception('ffsrequirement', $e);
    throw $e;
  }
}

/**
 * Deletes a wordgame word.
 *
 * @param $cid
 *   A ffsrequirement ID.
 */
function ffsrequirement_delete($wid) {
  ffsrequirement_delete_multiple(array($wid));
}

/**
 * Deletes multiple words.
 *
 * @param $cids
 *   An array of word IDs.
 */
function ffsrequirement_delete_multiple($rids) {
  $transaction = db_transaction();
  if (!empty($rids)) {
    $ffsrequirements = ffsrequirement_load_multiple($rids, array());

    try {
      foreach ($ffsrequirements as $wid => $ffsrequirement) {
        // Call the node-specific callback (if any):
        module_invoke_all('ffsrequirement_delete', $ffsrequirement);
        module_invoke_all('entity_delete', $ffsrequirement, 'ffsrequirement');
        field_attach_delete('ffsrequirement', $ffsrequirement);
      }
      // Delete after calling hooks so that they can query ffsrequirement tables as needed.
      db_delete('ffsrequirement')
        ->condition('rid', $rids, 'IN')
        ->execute();
    }
    catch (Exception $e) {
      $transaction->rollback();
      watchdog_exception('ffsrequirement', $e);
      throw $e;
    }

    // Clear the page and block and node_load_multiple caches.
    entity_get_controller('ffsrequirement')->resetCache();
  }
}

/**
 * Generates an array for rendering the given node.
 *
 * @param $node
 *   A node object.
 * @param $view_mode
 *   View mode, e.g. 'full', 'teaser'...
 * @param $langcode
 *   (optional) A language code to use for rendering. Defaults to the global
 *   content language of the current request.
 *
 * @return
 *   An array as expected by drupal_render().
 */
function ffsrequirement_view($ffsrequirement, $view_mode = 'full', $langcode = NULL) {
  if (!isset($langcode)) {
    $langcode = $GLOBALS['language_content']->language;
  }

  // Populate $node->content with a render() array.
  ffsrequirement_build_content($ffsrequirement, $view_mode, $langcode);

  $ffsrequirement->content['fullname'] = array(
    '#type' => 'item',
    '#title' => t('Fullname'),
    '#markup' => $ffsrequirement->fullname,
    '#weight' => -98
  );

  $ffsrequirement->content['year'] = array(
    '#type' => 'item',
    '#title' => t('Working year'),
    '#markup' => $ffsrequirement->year,
    '#weight' => -98
  );

  $build = $ffsrequirement->content;
  // We don't need duplicate rendering info in node->content.
  unset($ffsrequirement->content);

  $build += array(
    '#theme' => 'ffsrequirement',
    '#ffsrequirement' => $ffsrequirement,
    '#view_mode' => $view_mode,
    '#language' => $langcode,
  );



  // Add contextual links for this node, except when the node is already being
  // displayed on its own page. Modules may alter this behavior (for example,
  // to restrict contextual links to certain view modes) by implementing
  // hook_node_view_alter().
  if (!empty($ffsrequirement->rid) && !($view_mode == 'full')) {
    $build['#contextual_links']['ffsrequirement'] = array('ffsrequirement', array($ffsrequirement->rid));
  }

  // Allow modules to modify the structured node.
  $type = 'ffsrequirement';
  drupal_alter(array('ffsrequirement_view', 'entity_view'), $build, $type);

  return $build;
}

/**
 * Builds a structured array representing the node's content.
 *
 * The content built for the node (field values, comments, file attachments or
 * other node components) will vary depending on the $view_mode parameter.
 *
 * Drupal core defines the following view modes for nodes, with the following
 * default use cases:
 *   - full (default): node is being displayed on its own page (node/123)
 *   - teaser: node is being displayed on the default home page listing, on
 *     taxonomy listing pages, or on blog listing pages.
 *   - rss: node displayed in an RSS feed.
 *   If search.module is enabled:
 *   - search_index: node is being indexed for search.
 *   - search_result: node is being displayed as a search result.
 *   If book.module is enabled:
 *   - print: node is being displayed in print-friendly mode.
 * Contributed modules might define additional view modes, or use existing
 * view modes in additional contexts.
 *
 * @param $node
 *   A node object.
 * @param $view_mode
 *   View mode, e.g. 'full', 'teaser'...
 * @param $langcode
 *   (optional) A language code to use for rendering. Defaults to the global
 *   content language of the current request.
 */
function ffsrequirement_build_content($ffsrequirement, $view_mode = 'full', $langcode = NULL) {
  if (!isset($langcode)) {
    $langcode = $GLOBALS['language_content']->language;
  }

  // Remove previously built content, if exists.
  $ffsrequirement->content = array();

  // Allow modules to change the view mode.
  $context = array(
    'entity_type' => 'ffsrequirement',
    'entity' => $ffsrequirement,
    'langcode' => $langcode,
  );
  drupal_alter('entity_view_mode', $view_mode, $context);

  // Build fields content.
  // In case of a multiple view, node_view_multiple() already ran the
  // 'prepare_view' step. An internal flag prevents the operation from running
  // twice.
  field_attach_prepare_view('ffsrequirement', array($ffsrequirement->rid => $ffsrequirement), $view_mode, $langcode);
  entity_prepare_view('ffsrequirement', array($ffsrequirement->rid => $ffsrequirement), $langcode);
  $ffsrequirement->content += field_attach_view('ffsrequirement', $ffsrequirement, $view_mode, $langcode);

  // Always display a read more link on teasers because we have no way to know
  // when a teaser view is different than a full view.
  $links = array();
  $ffsrequirement->content['links'] = array(
    '#theme' => 'links__ffsrequirement',
    '#pre_render' => array('drupal_pre_render_links'),
    '#attributes' => array('class' => array('links', 'inline')),
  );

  // Allow modules to make their own additions to the node.
  module_invoke_all('ffsrequirement_view', $ffsrequirement, $view_mode, $langcode);
  module_invoke_all('entity_view', $ffsrequirement, 'ffsrequirement', $view_mode, $langcode);

  // Make sure the current view mode is stored if no module has already
  // populated the related key.
  $ffsrequirement->content += array('#view_mode' => $view_mode);
}


/**
 * Constructs a drupal_render() style array from an array of loaded nodes.
 *
 * @param $nodes
 *   An array of nodes as returned by node_load_multiple().
 * @param $view_mode
 *   View mode, e.g. 'full', 'teaser'...
 * @param $weight
 *   An integer representing the weight of the first node in the list.
 * @param $langcode
 *   (optional) A language code to use for rendering. Defaults to NULL which is
 *   the global content language of the current request.
 *
 * @return
 *   An array in the format expected by drupal_render().
 */
function ffsrequirement_view_multiple($ffsrequirements, $view_mode = 'teaser', $weight = 0, $langcode = NULL) {
  field_attach_prepare_view('ffsrequirement', $ffsrequirements, $view_mode, $langcode);
  entity_prepare_view('ffsrequirement', $ffsrequirements, $langcode);
  $build = array();
  foreach ($ffsrequirements as $ffsrequirement) {
    $build['ffsrequirements'][$ffsrequirement->rid] = ffsrequirement_view($ffsrequirement, $view_mode, $langcode);
    $build['ffsrequirements'][$ffsrequirement->rid]['#weight'] = $weight;
    $weight++;
  }
  $build['ffsrequirements']['#sorted'] = TRUE;
  return $build;
}

/**
 * Controller class for wordgame word.
 *
 * This extends the DrupalDefaultEntityController class, adding required
 * special handling for comment objects.
 */
class FFSRController extends DrupalDefaultEntityController {
  protected function attachLoad(&$ffsrequirements, $revision_id = FALSE) {
    // Call the default attachLoad() method. This will add fields and call
    // hook_wordgame_load().
    parent::attachLoad($ffsrequirements, $revision_id);
  }
}
